#include "util.h"
#include "log.h"

static char* log_file;
static FILE* log_fp;
static bool is_debug_enable;
static bool is_info_enable;
static bool is_error_enable;
#define max_log_file_size  (1024*1024)

void log_init(const char* file, bool debug_enabled, bool info_enabled, bool error_enabled)
{
	is_debug_enable = debug_enabled;
	is_info_enable = info_enabled;
	is_error_enable = error_enabled;

	if (file)
	{
		log_fp = fopen(file, "a");
		log_file = strdup(file);
	}

	if (!log_fp)
		log_fp = stdout;
}

void log_fini()
{
	if (log_fp != stdout)
		fclose(log_fp);

	if (log_file)
		free(log_file);

	log_fp = NULL;
	log_file = NULL;
	is_debug_enable = false;
	is_info_enable = true;
	is_error_enable = true;
}

static void check_log_file_size()
{
	if (!log_file || log_fp == stdout)
		return;

	struct stat st = { 0 };
	stat(log_file, &st);

	if (st.st_size > max_log_file_size)
	{
		fclose(log_fp);
		unlink(log_file);
		log_fp = fopen(log_file, "a");
	}
}

static void get_log_time(char* buf, size_t len)
{
	time_t now = time(NULL);
	struct tm* tm = localtime(&now);
	snprintf(buf, len, "%d-%02d-%02d %02d:%02d:%02d", 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
	buf[len - 1] = 0;
}

void log_debug(const char* format, ...)
{
	if (!is_debug_enable)
		return;

	check_log_file_size();

	char message[512] = { 0 };
	va_list va;
	va_start(va, format);
	vsnprintf(message, sizeof(message), format, va);
	message[sizeof(message) - 1] = 0;
	va_end(va);

	char time[32] = { 0 };
	get_log_time(time, sizeof(time));

	fprintf(log_fp, "%s [debug] %s\n", time, message);
	fflush(log_fp);
}


void log_info(const char* format, ...)
{
	if (!is_info_enable)
		return;

	check_log_file_size();

	char message[512] = { 0 };
	va_list va;
	va_start(va, format);
	vsnprintf(message, sizeof(message), format, va);
	message[sizeof(message) - 1] = 0;
	va_end(va);

	char time[32] = { 0 };
	get_log_time(time, sizeof(time));

	fprintf(log_fp, "%s [info ] %s\n", time, message);
	fflush(log_fp);
}

void log_error(const char* format, ...)
{
	if (!is_error_enable)
		return;

	check_log_file_size();

	char message[512] = { 0 };
	va_list va;
	va_start(va, format);
	vsnprintf(message, sizeof(message), format, va);
	message[sizeof(message) - 1] = 0;
	va_end(va);

	char time[32] = { 0 };
	get_log_time(time, sizeof(time));

	fprintf(log_fp, "%s [error] %s\n", time, message);
	fflush(log_fp);
}

void log_socket_error(int err, const char* format, ...)
{
	if (!is_error_enable)
		return;
	
	check_log_file_size();

	char message[512] = { 0 };
	va_list va;
	va_start(va, format);
	vsnprintf(message, sizeof(message), format, va);
	message[sizeof(message) - 1] = 0;
	va_end(va);

	const char* errstr = NULL;
	if (err)
		errstr = evutil_socket_error_to_string(err);
	
	char time[32] = { 0 };
	get_log_time(time, sizeof(time));

	fprintf(log_fp, "%s [error] %s [%s]\n", time, message, errstr ? errstr : "");
	fflush(log_fp);
}


